<?php
/**
 * Selector
 * @author Tomas Srna
 * @package bakalarka
 */

class Selector
{
	private $_db = NULL;
	private $_table = '';
	private $_what = '*';
	private $_where = '';
	private $_order = '';
	private $_limit = '';
	
	private $_fetch_class = '';
	
	/**
	 * Getter na db
	 * @return string db
	 */
	public function db()
	{
		return $this->_db;
	}
	
	/**
	 * Getter na fetch_class
	 * @return string fetch_class
	 */
	public function fetch_class()
	{
		return $this->_fetch_class;
	}
	
	/**
	 * Vytvorenie selectora
	 * @param PDO $adaptor Adapter databazoveho spojenia
	 */
	public function __construct($what = "*", $adaptor = NULL)
	{
		if($adaptor)
			$this->_db = $adaptor;
		else
			$this->_db = Db::instance();
		$this->_what = $what;
	}
	
	public static function select($what = "*")
	{
		return new Selector($what);
	}
	
	/**
	 * FROM
	 * @param string|Model $from	Zdroj
	 * @return Selector $this
	 */
	public function from($from)
	{
		if($from instanceof Model)
		{
			$this->table = $from->table();
			$this->_fetch_class = get_class($from);
		}
		// Derivovane tabulky musia mat alias
		else if($from instanceof Expression)
			$this->table = new Expression('('.$from.') as der');
		else if (is_string($from))
			$this->table = $from;
		
		return $this;
	}
	
	/**
	 * WHERE
	 * @param string $format	Formatovaci retazec, 
	 * 							? nahradza dalsimi argumentami
	 * @return Selector 		$this
	 */
	public function where()
	{
		$argc = func_num_args();
		$argv = func_get_args();
		
		if($argc < 2)
			return $this;
		
		$str = $argv[0];
		
		for ($i = 1; $i < $argc; ++$i)
		{
			$str = preg_replace('/\?/', ($argv[$i] instanceof Expression ?
				$argv[$i] : $this->_db->quote(addslashes($argv[$i]))), $str, 1);
		}
		
		$this->_where = $str;
		
		return $this;
	}
	
	/**
	 * ORDER BY
	 * @param string $order		Zoradovaci string
	 * @return Selector			$this
	 */
	public function order($by)
	{
		$this->_order = $by;
		
		return $this;
	}
	
	/**
	 * Zjednoduseny casto opakovany ORDER BY
	 * @param array $params		Parametre by a order
	 */
	public function by($params)
	{
		if(array_key_exists('by', $params))
		{
			$order = '`'.$params['by'].'`';
			if(array_key_exists('order', $params))
				$order .= ' '.$params['order'];
			$this->order($order);
		}
		
		return $this;
	}
	
	/**
	 * LIMIT
	 * @param int $start		Zaciatok
	 * @param int $count		Pocet
	 * @return Selector			$this
	 */
	public function limit($start, $count)
	{
		$this->_limit = "$start, $count";
		
		return $this;
	}
	
	/**
	 * Strankovanie
	 * @param int $page Stranka
	 */
	public function page($page)
	{
		$this->limit(($page-1)*Config::$itemsPerPage, 
							Config::$itemsPerPage);
		return $this;
	}
	
	/**
	 * Prevod na retazec
	 * @return string SQL
	 */
	public function __toString()
	{
		$r = "";
		
		if($this->table instanceof Expression)
			$r .= "SELECT {$this->_what} FROM (".$this->table.")";
		else
			$r .= "SELECT {$this->_what} FROM `".$this->table."`";
			
		if($this->_where)
			$r .= " WHERE " . $this->_where;
			
		if($this->_order)
			$r .= " ORDER BY " . $this->_order;
			
		if($this->_limit)
			$r .= " LIMIT " . $this->_limit;
		
		//$r .= ";";
		
		return $r;
		
	}
	
	/**
	 * Vykonanie SQL a ziskanie vysledkov
	 * @return Collection		Kolekcia vysladkov 
	 */
	public function fetch()
	{
		return new Collection($this);
	}
	
	/**
	 * Vymazanie vybranych poloziek
	 * @return bool 			Uspech
	 */
	public function delete() 
	{
		if(!$this->table)
			throw new Exception('L::noSourceTable');
		
		$r = "";
		
		$r .= "DELETE FROM `".$this->table."`";
		if($this->_where)
			$r .= " WHERE " . $this->_where;
			
		if($this->_order)
			$r .= " ORDER BY " . $this->_order;
			
		if($this->_limit)
			$r .= " LIMIT " . $this->_limit;
		
		$r .= ";";
		
		return $this->_db->query($r);
	}
}
